package com.icoolkj.api.wrap.core.utils;

import com.icoolkj.api.wrap.core.WrapData;
import com.icoolkj.api.wrap.core.annotation.SignIgnore;

import java.lang.reflect.Field;
import java.util.*;

/**
 * 改进的Bean转换工具，支持处理列表和嵌套对象
 * @author icoolkj
 */
public final class ImprovedWrapUtils {

    public static final String APP_KEY = "appKey";
    public static final String TIMESTAMP = "timestamp";
    public static final String NONCE = "nonce";

    private ImprovedWrapUtils() {
    }

    /**
     * 将对象转换为扁平化Map
     *
     * @param bean 待转换对象
     * @return 转换后的Map对象
     */
    public static <T> Map<String, Object> beanToMap(T bean) {
        if (bean == null) {
            return Collections.emptyMap();
        }
        return processObject("", bean, new HashMap<>());
    }

    /**
     * 递归处理对象及其字段
     *
     * @param prefix 字段前缀
     * @param object 待处理对象
     * @param resultMap 结果Map
     * @return 处理后的Map
     */
    private static Map<String, Object> processObject(String prefix, Object object, Map<String, Object> resultMap) {
        if (object == null) {
            return resultMap;
        }

        Class<?> clazz = object.getClass();
        
        // 处理基本类型直接返回
        if (isSimpleType(clazz)) {
            if (!prefix.isEmpty()) {
                resultMap.put(prefix, object);
            }
            return resultMap;
        }
        
        // 处理集合类型
        if (object instanceof Collection) {
            processCollection(prefix, (Collection<?>) object, resultMap);
            return resultMap;
        }
        
        // 处理Map类型
        if (object instanceof Map) {
            processMap(prefix, (Map<?, ?>) object, resultMap);
            return resultMap;
        }

        // 处理普通对象的字段
        // 向上循环遍历父类，直到WrapData
        for (; clazz != null && clazz != WrapData.class && clazz != Object.class; clazz = clazz.getSuperclass()) {
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                // 获取字段注解
                SignIgnore annotation = field.getAnnotation(SignIgnore.class);
                // 如果没有注解，则获取该值存入返回的map中
                if (annotation == null) {
                    field.setAccessible(true);
                    Object fieldVal = null;
                    try {
                        fieldVal = field.get(object);
                    } catch (IllegalAccessException ignored) {
                        continue;
                    }
                    
                    if (Objects.isNull(fieldVal)) {
                        continue;
                    }
                    
                    String fieldName = field.getName();
                    String fullName = prefix.isEmpty() ? fieldName : prefix + "." + fieldName;
                    
                    if (isSimpleType(fieldVal.getClass())) {
                        // 简单类型直接添加
                        resultMap.put(fullName, fieldVal);
                    } else if (fieldVal instanceof Collection) {
                        // 处理集合类型
                        processCollection(fullName, (Collection<?>) fieldVal, resultMap);
                    } else if (fieldVal instanceof Map) {
                        // 处理Map类型
                        processMap(fullName, (Map<?, ?>) fieldVal, resultMap);
                    } else {
                        // 递归处理复杂对象
                        processObject(fullName, fieldVal, resultMap);
                    }
                }
            }
        }
        
        return resultMap;
    }
    
    /**
     * 处理集合类型
     */
    private static void processCollection(String prefix, Collection<?> collection, Map<String, Object> resultMap) {
        int index = 0;
        for (Object item : collection) {
            if (item != null) {
                String indexKey = prefix + "[" + index + "]";
                if (isSimpleType(item.getClass())) {
                    resultMap.put(indexKey, item);
                } else {
                    processObject(indexKey, item, resultMap);
                }
            }
            index++;
        }
    }
    
    /**
     * 处理Map类型
     */
    private static void processMap(String prefix, Map<?, ?> map, Map<String, Object> resultMap) {
        for (Map.Entry<?, ?> entry : map.entrySet()) {
            Object key = entry.getKey();
            Object value = entry.getValue();
            
            if (key != null && value != null) {
                String mapKey = prefix + "[" + key + "]";
                if (isSimpleType(value.getClass())) {
                    resultMap.put(mapKey, value);
                } else {
                    processObject(mapKey, value, resultMap);
                }
            }
        }
    }
    
    /**
     * 判断是否为简单类型
     */
    private static boolean isSimpleType(Class<?> clazz) {
        return clazz.isPrimitive() || 
               Number.class.isAssignableFrom(clazz) ||
               String.class.equals(clazz) ||
               Boolean.class.equals(clazz) ||
               Character.class.equals(clazz) ||
               Date.class.equals(clazz) ||
               clazz.isEnum();
    }
} 